<?php

/**
 * Description of RapatRequest
 *
 * @author user
 */
class RapatRequest extends Rapat {

    public $room_name;

    public function beforeSave() {
        if (parent::beforeSave()) {
            $this->date = Util::convertDate($this->date);
            return true;
        }

        return false;
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules() {
        $rules = parent::rules();
        $rules[] = array('room_name', 'safe', 'on' => 'search');
        
        /*
         * date format must be dd/MM/yyyy, example 09/06/2011 mean 9 Juni 2011
         */
        $rules[] = array('date', 'date', 'format' => 'dd/MM/yyyy');
        
        /*
         * time format must be hh:mm, example 07:10 or 15:59
         */
        $rules[] = array('time_start, time_end', 'date', 'format' => 'hh:mm');
        
        /*
         * booking time must be grather or equal than today.
         * see function gratherEqualThanToday in this class for detail description.
         */
        $rules[] = array('time_start', 'graterEqualThanToday');
        
        /*
         * date must be valid before validate time_start or time_end.
         * see function depend in this class for detail description.
         */
        $rules[] = array('time_start, time_end', 'depend', 'attributeDepend' => 'date');
        
        /*
         * the value of time_end must be grater than time_start
         */
        $rules[] = array('time_end', 'compare', 'compareAttribute' => 'time_start', 'operator' => '>');
        
        /**
         * available of booking time must be checked when atribute time_end is validating.
         * see function isAvailable in this class for detail description.
         */
        $rules[] = array('time_end', 'isAvailable');
        
        /*
         * number of participant must be checked with capacity of room.
         * see function compareCapacity in this class for detail description.
         */
        $rules[] = array('participant', 'compareCapacity');
        
        return $rules;
    }

    public function searchRequest($status) {
        $criteria = new CDbCriteria;

        $criteria->with = array('room');

        $criteria->compare('t.id', $this->id);
        $criteria->compare('t.user_id', $this->user_id, true);
        $criteria->compare('t.name', $this->name, true);
        $criteria->compare('room.name', $this->room_name, true);
        $criteria->compare('date', $this->date, true);
        $criteria->compare('time_start', $this->time_start, true);
        $criteria->compare('time_end', $this->time_end, true);
        $criteria->compare('participant', $this->participant);
        $criteria->compare('message', $this->message, true);
        $criteria->compare('status', $status, true);

        return new CActiveDataProvider(get_class($this), array(
            'criteria' => $criteria,
            'sort' => array(
                'defaultOrder' => 't.id DESC',
            ),
        ));
    }

    public function searchWaitingRequest() {
        return $this->searchRequest('waiting');
    }

    public function searchApprovedRequest() {
        return $this->searchRequest('approved');
    }

    public function searchRejectedRequest() {
        return $this->searchRequest('rejected');
    }

    public function searchByUser($userId) {
        $criteria = new CDbCriteria;

        $criteria->with = array('room');

        $criteria->compare('t.id', $this->id);
        $criteria->compare('t.user_id', $userId);
        $criteria->compare('t.name', $this->name, true);
        $criteria->compare('room.name', $this->room_name, true);
        $criteria->compare('date', $this->date, true);
        $criteria->compare('time_start', $this->time_start, true);
        $criteria->compare('time_end', $this->time_end, true);
        $criteria->compare('participant', $this->participant);
        $criteria->compare('message', $this->message, true);
        $criteria->compare('status', $this->status, true);

        return new CActiveDataProvider(get_class($this), array(
            'criteria' => $criteria,
            'sort' => array(
                'defaultOrder' => 't.id DESC',
            ),
        ));
    }

    /**
     * Add error when attribute participant value grater than room capacity.
     * 
     * @param string $attribute spesific for attribute participant
     * @param array $params 
     */
    public function compareCapacity($attribute, $params) {
        if ($this->getError($attribute) != null)
            return;

        if ($this->getError($attribute) == null) {
            $model = Ruangan::model()->findByPk($this->room_id);
            if ($model != null) {
                if ($this->$attribute > $model->capacity) {
                    $this->addError($attribute, "Jumlah peserta tidak boleh lebih dari " . $model->capacity);
                }
            } else {
                $this->addError($attribute, "Ruangan tidak ditemukan.");
            }
        }
    }
    

    /**
     * Validate booking time. This function will use attribute date, time_start 
     * and time_end for validating.
     * 
     * Add error when booking time is just already booking or taken by other
     * user. Error will add to attribute date, time_start and time_end.
     *
     * @param string $attribute triggered attribute. Specific for time_end.
     * @param array $params not used.
     */
    public function isAvailable($attribute, $params) {
        if ($this->getError($attribute) != null)
            return;

        $time_start = $this->time_start;
        $time_end = $this->time_end;
        $date = Util::convertDate($this->date);

        $conditons = "
                    room_id = '$this->room_id' AND 
                    date = '$date' AND
                    status != 'rejected' AND
                    ((time_start <= '$time_start' AND time_end >= '$time_start') OR (time_start <= '$time_end' AND time_end >= '$time_start'))";

        $rapats = Rapat::model()->findAll($conditons);

        if (count($rapats) != 0) {
            $this->addError('time_start', "Waktu telah terpakai");
            $this->addError('time_end', "Waktu telah terpakai");
            $this->addError('date', "Waktu telah terpakai");
        }
    }

    
    /**
     * Used when certain attribute depend on other attribute. Error add when 
     * attributeDepend is empty or still have error.
     * 
     * Example :
     * array('time_start, time_end', 'depend', 'attributeDepend' => 'date');
     * 
     * @param string $attribute
     * @param array $params
     */
    public function depend($attribute, $params) {
        if ($this->getError($attribute) != null)
            return;

        $attrDepend = $params['attributeDepend'];
        if ($this->$attrDepend == "" || $this->getError($attrDepend) != null) {
            $labels = $this->attributeLabels();
            $this->addError($attribute, $labels[$attrDepend] . " harus valid / diisi terlebih dahulu");
        }
    }

    
    /**
     * Check booking time. Add error attribute to time_start or date when booking time is
     * less than current time.
     * 
     * @param string $attribute spesific for time_start
     * @param array $params
     */
    public function graterEqualThanToday($attribute, $params) {
        if ($this->getError('time_start') != null || $this->getError('date') != null)
            return;

        $timeStamp = time();
        $current = date("Y-m-d", $timeStamp);
        $converted = Util::convertDate($this->date);
        if ($current > $converted) {
            $this->addError('date', "Tanggal harus lebih besar dari atau sama dengan " . date("d/m/Y", $timeStamp));
        } else if ($current == $converted) {
            $current = date("H:i", $timeStamp);
            if ($current > $this->time_start) {
                $this->addError('time_start', $this->getAttributeLabel('time_start') . " harus lebih besar dari $current");
            }
        }
    }

}

?>
